package com.fowo.api.walmart.service;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.entity.TmpWfsCargo;
import com.fowo.api.entity.TmpWfsCargoItem;
import com.fowo.api.entity.WfsCargo;
import com.fowo.api.model.wfs.cargo.WfsCargoVo;
import com.fowo.api.model.wfs.cargo.item.WfsCargoItemItemVo;
import com.fowo.api.model.wfs.cargo.item.WfsCargoItemSearchParamPo;
import com.fowo.api.service.WfsCargoItemService;
import com.fowo.api.service.impl.WfsCargoServiceImpl;
import com.fowo.api.sys.entity.SysUser;
import com.fowo.api.sys.service.impl.SysUserServiceImpl;
import com.fowo.api.user.model.JwtUserInfo;
import com.fowo.api.walmart.api.WalmartShipmentApi;
import com.fowo.api.walmart.mapper.SyncWalmartMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SyncWalmartShipmentServiceImpl {
    @Resource
    private SyncWalmartMapper syncWalmartMapper;
    @Resource
    private WalmartShipmentApi walmartShipmentApi;
    @Resource
    private WfsCargoServiceImpl wfsCargoService;
    @Resource
    private WfsCargoItemService wfsCargoItemService;
    @Resource
    private SysUserServiceImpl userService;

    public void syncShipments() throws Exception {
        //清空临时表数据
        syncWalmartMapper.deleteTmpShipments();
        syncWalmartMapper.deleteTmpShipmentsItem();

        final List<TmpWfsCargo> newShipments = walmartShipmentApi.getShipments();
        final List<String> shipmentIds = newShipments.stream().map(s -> s.getShipmentId()).collect(Collectors.toList());
        final List<WfsCargo> oldWfsCargo = wfsCargoService.list(Wrappers.lambdaQuery(WfsCargo.class).in(WfsCargo::getCargoCode, shipmentIds));

        List<TmpWfsCargoItem> newItems = walmartShipmentApi.getShipmentItems(newShipments);
        saveShipments(newShipments,newItems,oldWfsCargo);
    }

    public void saveShipments(List<TmpWfsCargo> newShipments,List<TmpWfsCargoItem> newItems,List<WfsCargo> oldWfsCargos) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        Long userId = null;
        if(currentUser != null){
            userId = currentUser.getUserId();
        }else {
            userId = userService.getByUsername("admin").getId();
        }
        for(TmpWfsCargo tmpWfsCargo : newShipments){
            WfsCargo wfsCargo = oldWfsCargos.stream()
                    .filter(old -> old.getInBoundOrderId().equals(tmpWfsCargo.getInboundOrderId())&&old.getCargoCode().equals(tmpWfsCargo.getShipmentId()))
                    .findAny()
                    .orElse(null);
            if(null == wfsCargo){//新增
                WfsCargoVo wfsCargoVo = new WfsCargoVo();
                wfsCargoVo.setCargoCode(tmpWfsCargo.getShipmentId());
                wfsCargoVo.setShopId(tmpWfsCargo.getSid());
                wfsCargoVo.setLogisticsCode(tmpWfsCargo.getToFcName());
                wfsCargoVo.setInBoundOrderId(tmpWfsCargo.getInboundOrderId());
                wfsCargoVo.setDistributionAddresses(tmpWfsCargo.getToAddressLine1()+","
                        +tmpWfsCargo.getToCity()+","
                        +tmpWfsCargo.getToStateCode()+","
                        +tmpWfsCargo.getToCountryCode()+","
                        +tmpWfsCargo.getToPostalCode());
                wfsCargoVo.setCountryName(tmpWfsCargo.getCountryName());
                wfsCargoVo.setDetailedAddress(tmpWfsCargo.getReturnAddressLine1());
                wfsCargoVo.setCargoStatus(tmpWfsCargo.getStatus());
//                wfsCargoVo.setShippingListCodes(tmpWfsCargo.getTrackingNo());
                wfsCargoVo.setContractors(tmpWfsCargo.getCarrierName());

                wfsCargoVo.setCtiy(tmpWfsCargo.getReturnCity());
                wfsCargoVo.setArea(tmpWfsCargo.getReturnStateCode());
                wfsCargoVo.setPostalCode(tmpWfsCargo.getReturnPostalCode());
                if(tmpWfsCargo.getStatus().equals("CLOSED")){
                    wfsCargoVo.setCompletedTime(new Date());
                }
                final List<TmpWfsCargoItem> itemList = newItems.stream().filter(i -> i.getShipmentId().equals(tmpWfsCargo.getShipmentId())).collect(Collectors.toList());

                List<WfsCargoItemItemVo> items = new ArrayList<>();
                int cases = 0;
                for(TmpWfsCargoItem tmpWfsCargoItem : itemList){
                    WfsCargoItemItemVo itemVo = new WfsCargoItemItemVo();
                    itemVo.setImg("");
                    itemVo.setMsku(tmpWfsCargoItem.getSku());
                    itemVo.setGtin(tmpWfsCargoItem.getGtin());
                    itemVo.setProductName(tmpWfsCargoItem.getProductName());
                    itemVo.setSku(tmpWfsCargoItem.getLocalSku());
//                    itemVo.setProductName();
                    itemVo.setProductDescribe(tmpWfsCargoItem.getItemDesc());
                    itemVo.setDeclareNum(tmpWfsCargoItem.getItemQty() == null ? 0 : tmpWfsCargoItem.getItemQty());
//                    itemVo.setShipstatus();
                    itemVo.setReceivedquantity(tmpWfsCargoItem.getReceivedQty() == null ? 0L : tmpWfsCargoItem.getReceivedQty().longValue());
                    itemVo.setReceivedNum(tmpWfsCargoItem.getDamagedQty() == null ? 0 : tmpWfsCargoItem.getDamagedQty());
                    itemVo.setBoxNum(tmpWfsCargoItem.getVendorPackQty() == null ? 0 : tmpWfsCargoItem.getVendorPackQty());
                    cases += itemVo.getBoxNum();
                    itemVo.setSingleboxquantity(tmpWfsCargoItem.getInnerPackQty() == null ? 0 : tmpWfsCargoItem.getInnerPackQty());
                    itemVo.setEstimatedExpirationTime(tmpWfsCargoItem.getExpectedDeliveryDate());
                    itemVo.setShipmentsNum(tmpWfsCargoItem.getItemQty() == null ? 0 : tmpWfsCargoItem.getItemQty());
                    itemVo.setShenfadifference(itemVo.getDeclareNum() - itemVo.getShipmentsNum());
                    itemVo.setShenshoudifference(itemVo.getDeclareNum() - itemVo.getReceivedquantity().intValue());
                    itemVo.setShoufadifference(itemVo.getReceivedquantity().intValue() - itemVo.getShipmentsNum());
                    items.add(itemVo);
                }
                wfsCargoVo.setCases(cases);
                wfsCargoVo.setItems(items);
                wfsCargoVo.setCreateUser(userId);
                wfsCargoVo.setLastUpdateUser(userId);
                wfsCargoService.create(wfsCargoVo);
            }else{//更新
                wfsCargo.setCargoStatus(tmpWfsCargo.getStatus());

                WfsCargoVo wfsCargoVo = new WfsCargoVo();
                BeanUtil.copyProperties(wfsCargo,wfsCargoVo);

                WfsCargoItemSearchParamPo itemsSearchParamPo = new WfsCargoItemSearchParamPo();
                List<WfsCargoItemItemVo> oldItems =  wfsCargoItemService.search(itemsSearchParamPo);
                List<WfsCargoItemItemVo> updateItems = new ArrayList<>();
                while(!oldItems.isEmpty()){
                    WfsCargoItemItemVo itemVo = oldItems.get(0);
                    oldItems.remove(itemVo);

                    final TmpWfsCargoItem newItem = newItems.stream().filter(i -> i.getSku().equals(itemVo.getMsku()) && i.getShipmentId().equals(tmpWfsCargo.getShipmentId())).findAny().orElse(null);
                    if(null != newItem){
                        //declareNum
                        itemVo.setDeclareNum(newItem.getItemQty());
                        itemVo.setReceivedquantity(newItem.getReceivedQty() == null ? 0L : newItem.getReceivedQty().longValue());
                        itemVo.setReceivedNum(newItem.getDamagedQty() == null ? 0 : newItem.getDamagedQty());
                        itemVo.setShoufadifference(itemVo.getReceivedquantity().intValue() - itemVo.getShipmentsNum());
                        itemVo.setShenshoudifference(itemVo.getDeclareNum() - itemVo.getReceivedquantity().intValue());
                        updateItems.add(itemVo);
                    }
                }
                wfsCargoVo.setItems(updateItems);
                wfsCargoVo.setLastUpdateUser(userId);
                wfsCargoService.update(wfsCargoVo);
            }
        }
    }

//    public List<TmpWfsCargo> compareShipmentsNewOrOldData(List<TmpWfsCargo> newShipments,List<WfsCargo> oldWfsCargos){
//        List<TmpWfsCargo> result = new ArrayList<>();
//        List<TmpWfsCargo> inserts = new ArrayList<>();
//        while (!newShipments.isEmpty()){
//            TmpWfsCargo tmpWfsCargo = newShipments.get(0);
//            newShipments.remove(tmpWfsCargo);
//
//            WfsCargo wfsCargo = oldWfsCargos.stream()
//                    .filter(old -> old.getInBoundOrderId().equals(tmpWfsCargo.getInboundOrderId())&&old.getCargoCode().equals(tmpWfsCargo.getShipmentId()))
//                    .findAny()
//                    .orElse(null);
//            if(null == wfsCargo){
//                tmpWfsCargo.setIsUpdate(false);
//                inserts.add(tmpWfsCargo);
//            }else {
//                tmpWfsCargo.setIsUpdate(true);
//            }
//            result.add(tmpWfsCargo);
//        }
//        tmpWfsCargoService.saveBatch(result);
//        return inserts;
//    }

    public void syncShipmentsByShop(Long shopId,List<String> shipmentIds) throws Exception{
        //清空临时表数据
        syncWalmartMapper.deleteTmpShipments();
        syncWalmartMapper.deleteTmpShipmentsItem();
        //货件主体信息
        final List<TmpWfsCargo> newShipments = walmartShipmentApi.getShipmentsByShop(shopId, shipmentIds);

        shipmentIds = newShipments.stream().map(s -> s.getShipmentId()).collect(Collectors.toList());
        final List<WfsCargo> oldWfsCargo = wfsCargoService.list(Wrappers.lambdaQuery(WfsCargo.class).in(WfsCargo::getCargoCode, shipmentIds));
        //货件产品信息
        List<TmpWfsCargoItem> newItems = walmartShipmentApi.getShipmentItems(newShipments);
        //保存到业务表
        saveShipments(newShipments,newItems,oldWfsCargo);
    }
}
